<template>
  <a-radio-group v-if="compType === CompTypeEnum.Radio" v-bind="attrs" v-model:value="state" @change="handleChangeRadio">
    <template v-for="item in dictOptions" :key="`${item.value}`">
      <a-radio :value="item.value">
        {{ item.label }}
      </a-radio>
    </template>
  </a-radio-group>

  <a-radio-group
    v-else-if="compType === CompTypeEnum.RadioButton"
    v-bind="attrs"
    v-model:value="state"
    buttonStyle="solid"
    @change="handleChangeRadio"
  >
    <template v-for="item in dictOptions" :key="`${item.value}`">
      <a-radio-button :value="item.value">
        {{ item.label }}
      </a-radio-button>
    </template>
  </a-radio-group>

  <template v-else-if="compType === CompTypeEnum.Select">
    <!-- 显示加载效果 -->
    <a-input v-if="loadingEcho" readOnly placeholder="加载中…">
      <template #prefix>
        <LoadingOutlined />
      </template>
    </a-input>
    <a-select
      v-else
      :placeholder="placeholder"
      v-bind="attrs"
      v-model:value="state"
      option-label-prop="label"
      :filterOption="handleFilterOption"
      :getPopupContainer="getPopupContainer"
      @change="handleChange"
    >
      <a-select-option v-if="showChooseOption" :value="null">{{ chooseOptionLabel }}</a-select-option>
      <template v-for="item in dictOptions" :key="`${item.value}`">
        <a-select-option :value="item.value" :label="item.label">
          <span style="display: inline-block; width: 100%" :title="item.label">
            {{ item.label }}
          </span>
          
          <!-- <span style="display: inline-block; width: 100%" :title="item.label">
            <span>{{ item.label }}</span>
            <a-icon style="float: right; margin-left: 5px;" type="edit" @click.stop=""/>
          </span> -->
        </a-select-option>
      </template>
    </a-select>
  </template>
</template>
<script lang="ts">
import {computed, defineComponent, nextTick, ref, unref, watch, watchEffect} from 'vue';
import {propTypes} from '/@/utils/propTypes';
import {useAttrs} from '/@/hooks/core/useAttrs';
import {initDictOptions} from '/@/utils/dict';
import {omit} from 'lodash-es';
import {useRuleFormItem} from '/@/hooks/component/useFormItem';
import {CompTypeEnum} from '/@/enums/CompTypeEnum';
import {LoadingOutlined} from '@ant-design/icons-vue';

export default defineComponent({
    name: 'JDictSelectTag',
    inheritAttrs: false,
    components: { LoadingOutlined },
    props: {
      value: propTypes.oneOfType([propTypes.string, propTypes.number, propTypes.array, propTypes.bool]),
      dictCode: propTypes.string,
      type: propTypes.string,
      placeholder: propTypes.string,
      stringToNumber: propTypes.bool,
      stringToBool: propTypes.bool,
      // 过滤字典, 为true时, 才展示
      filter: {
        type: Function,
        default: (item) => true,
      },
      getPopupContainer: {
        type: Function,
        default: (node) => node.parentNode,
      },
      // 是否显示【请选择】选项
      showChooseOption: propTypes.bool.def(true),
      chooseOptionLabel: propTypes.string.def('请选择…'),
      // 下拉项-online使用
      options: {
        type: Array,
        default: [],
        required: false,
      },
    },
    emits: ['options-change', 'change', 'update:value'],
    setup(props, { emit, refs }) {
      const dictOptions = ref<any[]>([]);
      const attrs = useAttrs();
      const [state, , , formItemContext] = useRuleFormItem(props, 'value', 'change');
      const getBindValue = Object.assign({}, unref(props), unref(attrs));
      // 是否正在加载回显数据
      const loadingEcho = ref<boolean>(false);
      // 是否是首次加载回显，只有首次加载，才会显示 loading
      let isFirstLoadEcho = true;

      //组件类型
      const compType = computed(() => {
        return !props.type || props.type === 'list' ? 'select' : props.type;
      });
      /**
       * 监听字典code
       */
      watchEffect(() => {
        if (props.dictCode) {
          loadingEcho.value = isFirstLoadEcho;
          isFirstLoadEcho = false;
          initDictData().finally(() => {
            loadingEcho.value = isFirstLoadEcho;
          });
        }
        // 如果没有提供dictCode 可以走options的配置--
        if (!props.dictCode) {
          dictOptions.value = props.options.filter(e => props.filter(e.value));
        }
      });

      // 使用useRuleFormItem定义的value，会有一个问题，如果不是操作设置的值而是代码设置的控件值而不能触发change事件
      // 此处添加空值的change事件,即当组件调用地代码设置value为''也能触发change事件
      watch(
        () => props.value,
        () => {
          if (props.value === '') {
            emit('change', '');
            emit('update:value', '')
            nextTick(() => formItemContext.onFieldChange());
          }
        }
      );
   
      async function initDictData() {
        let { dictCode, stringToNumber, stringToBool } = props;
        //根据字典Code, 初始化字典数组
        const dictData = await initDictOptions(dictCode);
        dictOptions.value = dictData.filter(e => props.filter(e.value)).reduce((prev, next) => {
          if (next) {
            let value = next['value'];
            value = stringToBool ? value === 'true' || value === '1' : value
            prev.push({
              label: next['text'] || next['label'],
              value: stringToNumber ? + value : value,
              ...omit(next, ['text', 'value']),
            });
          }
          return prev;
        }, []);
      }

      function handleChange(e) {
        const { mode } = unref<Recordable>(getBindValue);
        // 兼容多选模式
        if (mode === 'multiple') {
          state.value = e?.target?.value ?? e;
        } else {
          state.value = [e?.target?.value ?? e];
        }
        // 过滤掉空值
        if (state.value == null || state.value === '') {
          state.value = [];
        }
        if (Array.isArray(state.value)) {
          state.value = state.value.filter((item) => item != null && item !== '');
        }
        emit('update:value', state.value)
        // nextTick(() => formItemContext.onFieldChange());
      }

      /** 单选radio的值变化事件 */
      function handleChangeRadio(e) {
        state.value = e?.target?.value ?? e;
        emit('update:value', state.value)
      }

      /** 用于搜索下拉框中的内容 */
      function handleFilterOption(input, option) {
        // 在 label 中搜索
        let labelIf = option.children()[0]?.children.toLowerCase().indexOf(input.toLowerCase()) >= 0;
        if (labelIf) {
          return true;
        }
        // 在 value 中搜索
        return (option.value || '').toString().toLowerCase().indexOf(input.toLowerCase()) >= 0;
      }

      return {
        state,
        compType,
        attrs,
        loadingEcho,
        getBindValue,
        dictOptions,
        CompTypeEnum,
        handleChange,
        handleChangeRadio,
        handleFilterOption,
      };
    },
  });
</script>
